using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.IO;
using UnityEngine;
using UnityEditor;

public class lwBuilder : EditorWindow 
{	
	
	//AB CREATOR
	string[] m_xmlPathArray = null;
	string[] m_xmlNameArray = null;
	bool[] m_abSelectArray = null;
	bool bSelectAllFonts = false;
	bool bSelectAllLanguages = false;
	bool bSelectAllAssetBundles = false;
	
	enum State { None, BuildAB, BuildEditor };
	private State m_nState = State.None;

	private string langPath = "Assets/Resources/Texts/Langs.txt";
	private string langEncPath = "External/Langs.enc";
	private string settingsPath = "Assets/Resources/Settings.txt";
	private string settingsEncPath = "External/Settings.enc";

	private static lwBuilder window = null;

	//langages
	private string[] languages = 	{ "Latin",	"Japenese",	"Korean",	"Chinese",	"Russian" };
	private string[] suffixes = 	{ "LN",		"JP",		"KR",		"CN",		"RU" };
	private bool[] versions = 		{ false,	false,		false,		false,		false };
	private string[] latinLangs =		{ "English",	"French",	"Spanish",	"German",	"Italian",	"Dutch",	"Portuguese",	"Swedish", "Polish" };
	private string[] latinSuffixes =	{ "EN",			"FR",		"SP",		"GE",		"IT",		"NL",		"PO",			"SW", "PL" };
	// 12 choix de langages
	private bool[] bLanguages = 		{ false, false, false, false, false, false, false, false, false, false, false, false, false };
		
	private bool bBuildFonts = false;
	private bool bBuildLanguages = false;
	private bool bBuildGame = false;
	private BuildTarget[] targetList = {BuildTarget.StandaloneWindows, BuildTarget.StandaloneOSXIntel, BuildTarget.Android, BuildTarget.iPhone, BuildTarget.WebPlayer};
	private string[] targetListName = null;
	private int nSelectedIndexTarget = 0;
	
	GUIStyle titleStyle = new GUIStyle();
	
	private static bool m_bInitDone = false;
	
	
	[MenuItem("Tools/LWS/Builder...", false, 0)]
	static public void Init()
	{
		m_bInitDone = false;
		window = EditorWindow.GetWindow( typeof(lwBuilder) ) as lwBuilder;
		if (window != null)
		{
			window.InitAll();
		}
		m_bInitDone = true;
	}
	
	void InitAll()
	{
		lwBuildSettings.Load();
		LoadAssetBundles();
		LoadLanguagesSettings();
		InitStyle();
		InitTargets();
		m_bInitDone = true;
	}
	
	void InitTargets()
	{
		targetListName = new string[targetList.Length];
		for(int i = 0; i < targetList.Length; i++)
			targetListName[i] = System.Enum.GetName(typeof(BuildTarget), targetList[i]);
		nSelectedIndexTarget = Array.IndexOf(targetList, EditorUserBuildSettings.activeBuildTarget);
		if(nSelectedIndexTarget == -1)
			nSelectedIndexTarget = 0;
	}
	
	
	void InitStyle() 
	{
		titleStyle.font = EditorStyles.whiteLargeLabel.font;
		titleStyle.fontSize = EditorStyles.whiteLargeLabel.fontSize;
		titleStyle.fontStyle = EditorStyles.whiteLargeLabel.fontStyle;
		titleStyle.fixedHeight = 20;
		titleStyle.alignment = TextAnchor.MiddleCenter;
		titleStyle.normal.textColor = EditorStyles.whiteLargeLabel.normal.textColor;
		titleStyle.normal.background = EditorStyles.toolbar.normal.background;
	}

	void LoadAssetBundles()
	{
		if(!Directory.Exists(Application.dataPath + "/../Data/AssetBundles"))
			return;
		m_xmlPathArray = Directory.GetFiles( "../Data/AssetBundles", "*.xml" );
		
		if ( m_xmlPathArray == null || m_xmlPathArray.Length <= 0 )
			return;
		
		List<string> tmpXmlPathArray = new List<string>( m_xmlPathArray );
		//int nLastIndex;
		
		// Remove fonts from the list
		for( int i = 0; i < tmpXmlPathArray.Count; i++ )
		{
			/*nLastIndex = tmpXmlPathArray[i].LastIndexOf( '\\' );
			nLastIndex = nLastIndex < 0 ? 0 : nLastIndex + 1;
			
			if( tmpXmlPathArray[i].Length > nLastIndex + 4 
				&& tmpXmlPathArray[i].Substring( nLastIndex, 5 ) == "Fonts" )*/
			if(tmpXmlPathArray[i].Contains("Fonts"))
			{
				tmpXmlPathArray.RemoveAt( i );
				i--;
			}
		}
		
		for( int i = 0; i < tmpXmlPathArray.Count; i++ )
		{
			XmlReader xr = XmlReader.Create( tmpXmlPathArray[i] );
			string sBundleVersions = string.Empty;
			string sVersion = GetVersionName();
	        while (xr.Read())
	        {
	            if (xr.NodeType == XmlNodeType.Element && xr.Name.ToUpper() == "BUNDLE")
				{
					sBundleVersions = xr.GetAttribute( "version" );
					if(sBundleVersions != null)
					{
						if(!sBundleVersions.ToUpper().Contains(sVersion.ToUpper()))
						{
							tmpXmlPathArray.RemoveAt( i );
							i--;
						}
					}
					break;
				}
			}
		}
		
		m_xmlPathArray = tmpXmlPathArray.ToArray();
		
		m_abSelectArray = new bool[m_xmlPathArray.Length];
		m_xmlNameArray = new string[m_xmlPathArray.Length];
		for (int i=0; i<m_xmlPathArray.Length; i++)
		{
			m_abSelectArray[i] = false;
			m_xmlNameArray[i] = Path.GetFileName(m_xmlPathArray[i]);
		}
	}
	
	void LoadLanguagesSettings()
	{
			for(int i = 0; i < bLanguages.Length; i++)
				bLanguages[i] = false;
		
			if(!File.Exists(langPath))
				return;
		
			StreamReader sr = new StreamReader(langPath);
			if(sr == null)
				return;
		
			string sText = sr.ReadToEnd();
			sr.Close();
			
			int nLanguages = 0;
		
			for(int i = 0; i < latinSuffixes.Length; i++)
			{
				if(sText.Contains(latinSuffixes[i])) {
					bLanguages[i] = true;
					nLanguages++;
				}
			}
		
			for(int i = 1; i < suffixes.Length; i++)
			{
				if(sText.Contains(suffixes[i])) {
					bLanguages[i + latinSuffixes.Length - 1] = true;
					nLanguages++;
				}
			}
		
			if(nLanguages == bLanguages.Length)
				bSelectAllLanguages = true;
	}
		
	//A redefinir dans les differents projets ?
	string GetVersionName()
	{
		return lwBuildSettings.GetVariableValue( "GAME_VERSION" );
//		return GameContext.GetCurrentGameName();
	}
	
	void OnGUI()
	{	
		
		if(m_bInitDone)
		{	
			int i;
			
			//VARIABLES
	
			GUILayout.BeginArea (new Rect (10,10,180,580), "");
			
			GUILayout.Label ("Variables", titleStyle);
			string sModifiedKey = "";
			string sModifiedValue = "";
			foreach (KeyValuePair<string,lwBuildVariable> v in lwBuildSettings.Variables)
			{
				if ( v.Value.m_bBuilderVisibility )
				{
					string sVarName = v.Key;
					string sEnumValues = lwBuildSettings.GetEnumVariableValues(sVarName);
					if ( !string.IsNullOrEmpty( sEnumValues ) )
					{
						string[] sEnumValuesArray = sEnumValues.Split(',');
						int nOldSelectedIndex = lwBuildSettings.GetEnumVariableValue(sVarName);
						
						GUILayout.BeginHorizontal();
						GUILayout.Label(sVarName);
						int nNewSelectedIndex = EditorGUILayout.Popup(nOldSelectedIndex, sEnumValuesArray);
						GUILayout.EndHorizontal();
		
						if (nNewSelectedIndex != nOldSelectedIndex)
						{
							sModifiedKey = sVarName;
							sModifiedValue = sEnumValuesArray[nNewSelectedIndex];
						}
					}
					else
					{			
						bool bOldValue = lwBuildSettings.GetBoolVariableValue(sVarName);
						bool bValue = EditorGUILayout.Toggle( v.Key, bOldValue);
						if (bValue != bOldValue)
						{
							sModifiedKey = sVarName;
							sModifiedValue = bValue ? "true" : "false";
						}
					}
				}
			}
			if (sModifiedKey != "")
			{
				lwBuildSettings.SetVariableValue(sModifiedKey, sModifiedValue);
				lwBuildSettings.Save();
				if(sModifiedKey.ToUpper() == "GAME_VERSION") {
					LoadAssetBundles();
				}
			}
	
			if ( GUILayout.Button( "Reload" ) )
			{
				lwBuildSettings.Load();
			}
			
			
			//GUILayout.EndArea ();		
			
			//AB CREATOR
			//GUILayout.BeginArea (new Rect (210,10,180,380), "", EditorStyles.toolbar);
			GUILayout.Label ("Asset Bundles", titleStyle);
			if ( m_xmlNameArray != null && m_xmlNameArray.Length > 0 )
			{
				//select all/unselect all
				bool bNewValue = EditorGUILayout.Toggle( "Select all", bSelectAllAssetBundles);
				if (bNewValue != bSelectAllAssetBundles)
				{
					bSelectAllAssetBundles = bNewValue;
					for (i=0; i<m_abSelectArray.Length; i++)
					{
						m_abSelectArray[i] = bSelectAllAssetBundles;
					}
				}
	
				for (i=0; i<m_xmlNameArray.Length; i++)
				{
					m_abSelectArray[i] = EditorGUILayout.Toggle( m_xmlNameArray[i], m_abSelectArray[i]);
				}
	
				if ( m_nState == State.None	) 
				{
					if ( GUILayout.Button( "Build assetbundles !" ) )
						m_nState = State.BuildAB;
				}
			}
			else
			{
				GUILayout.Label ("No XML file found in AssetBundles directory !", EditorStyles.boldLabel);
			}
			GUILayout.EndArea ();
			
			//Fonts CREATOR
			
			GUILayout.BeginArea (new Rect (200,10,180,580), "");
			
			GUILayout.Label ("Fonts", titleStyle);
			
			bool bNewValue2 = EditorGUILayout.Toggle( "Select all", bSelectAllFonts );
			
			if ( bNewValue2 != bSelectAllFonts )
			{
				bSelectAllFonts = bNewValue2;
				
				for( i = 0; i < versions.Length; i++)
					versions[i] = bSelectAllFonts;
			}
			
			for ( i = 0; i < languages.Length; i++ )
				versions[i] = EditorGUILayout.Toggle( languages[i], versions[i], GUILayout.Width( 300 ) );
	
			GUILayout.Space( 10 );
			
			if ( GUILayout.Button( "Build Fonts" ) )
			{
				bBuildFonts = true;
			}
			
			//Languages CREATOR
			
			GUILayout.Label ("Languages", titleStyle);
			
			bool bNewValue3 = EditorGUILayout.Toggle( "Select all", bSelectAllLanguages );
			
			if ( bNewValue3 != bSelectAllLanguages )
			{
				bSelectAllLanguages = bNewValue3;
				
				for( i = 0; i < bLanguages.Length; i++)
					bLanguages[i] = bNewValue3;
			}
			
			for ( i = 0; i < latinLangs.Length; i++ )
				bLanguages[i] = EditorGUILayout.Toggle( latinLangs[i], bLanguages[i], GUILayout.Width( 300 ) );
			for ( i = 1; i < languages.Length; i++ )
				bLanguages[i + latinLangs.Length - 1] = EditorGUILayout.Toggle( languages[i], bLanguages[i + latinLangs.Length - 1], GUILayout.Width( 300 ) );
			
			GUILayout.Space( 10 );
			
			if ( GUILayout.Button( "Build Languages" ) )
			{
				bBuildLanguages = true;
			}
			
			GUILayout.EndArea ();
	
			GUILayout.BeginArea (new Rect (400,10,180,200), "");
			
	//		GUILayout.BeginHorizontal();
			GUILayout.Label("Target", titleStyle);
			nSelectedIndexTarget = EditorGUILayout.Popup(nSelectedIndexTarget, targetListName);
	//		GUILayout.EndHorizontal();
			
			GUILayout.BeginHorizontal();
			if ( GUILayout.Button( "Switch Platform" ) && targetList[nSelectedIndexTarget] != EditorUserBuildSettings.activeBuildTarget) {
				SwitchPlatform();	
			}
			
			if ( GUILayout.Button( "Build" ) )
			{
				bBuildGame = true;
			}
			GUILayout.EndHorizontal();
			
			GUILayout.EndArea ();
		}
	}
	
	
	
	bool IsReleaseBuild()
	{
		return lwBuildSettings.GetBoolVariableValue("RELEASE");
	}
	
	//AB CREATOR

	void BuildAssetBundles()
	{
		if(!Directory.Exists(Application.dataPath + "/../../Build/" + EditorUserBuildSettings.activeBuildTarget + "/AssetBundles/" + lwBuildSettings.GetGameVersionName()))
			Directory.CreateDirectory(Application.dataPath + "/../../Build/" + EditorUserBuildSettings.activeBuildTarget + "/AssetBundles/" + lwBuildSettings.GetGameVersionName());
		
		int nCount = 0;
		Debug.Log( "Build launched" );
		for(int i=0; i<m_xmlPathArray.Length; i++)
		{
			if ( m_abSelectArray[i] )
			{
				BuildAssetBundle( m_xmlPathArray[i] );
				nCount++;
			}
		}
		Debug.Log( nCount.ToString() + " assetbundles generated." );
		
		
	}
	
	void BuildAssetBundle( string sFileName ) 
	{
		XmlReader xr = XmlReader.Create( sFileName );
		ArrayList rscArray = new ArrayList();
		string sBundleName = string.Empty;
		string sVersion, sPath;
        while (xr.Read())
        {
            if (xr.NodeType == XmlNodeType.Element )
			{
				switch( xr.Name.ToUpper() )
				{
				case "BUNDLE":
					sBundleName = xr.GetAttribute( "name" );
					Debug.Log( "Creating a new bundle : " + sBundleName );
					break;
				case "RSC":
					if ( (EditorUserBuildSettings.activeBuildTarget != BuildTarget.iPhone 
					    	|| lwBuildSettings.GetXmlAttributeBool( xr, "iOS", true ) )
						&& (EditorUserBuildSettings.activeBuildTarget != BuildTarget.Android 
					    	|| lwBuildSettings.GetXmlAttributeBool( xr, "android", true ) )
						)
					{
						string sName = xr.GetAttribute( "name" );
						sVersion = GetVersionName();
						sPath = "Assets/Specific/" + sVersion + "/" + sName;
						UnityEngine.Object o = AssetDatabase.LoadMainAssetAtPath( sPath );
						if ( o == null )
						{
							sPath = "Assets/" + sName;
							o = AssetDatabase.LoadMainAssetAtPath( sPath );
						}
						if ( o == null )
						{
							Debug.LogWarning( "ASSET " + sName + " can't be loaded !" );
						}
						else
						{
							Debug.Log( "Adding resource " + sPath );
							rscArray.Add( o );
						}
					}
					break;
				}
			}
			else if ( xr.NodeType == XmlNodeType.EndElement )
			{
				if ( xr.Name.ToUpper() == "BUNDLE" )
				{ // Actualy write the bundle
					UnityEngine.Object[] rscObjArray = rscArray.ToArray(typeof(UnityEngine.Object)) as UnityEngine.Object[];
					sVersion = GetVersionName();
					if ( EditorUserBuildSettings.activeBuildTarget == BuildTarget.iPhone)
						sPath = "../Build/iOSFinal/AssetBundles/" + sVersion + "/" + sVersion + "_" + sBundleName + ".assetbundle";
					else  if ( EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
						sPath = "../Build/Android/AssetBundles/" + sVersion + "/" + sVersion + "_" + sBundleName + ".assetbundle";
					else
						sPath = "../Build/PC/AssetBundles/" + sVersion + "/" + sVersion + "_" + sBundleName + ".assetbundle";
					
					BuildAssetBundleOptions options = BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets;			
					BuildTarget target = EditorUserBuildSettings.activeBuildTarget;

					bool bSuccess = BuildPipeline.BuildAssetBundle( null, rscObjArray, sPath, options, target );

					if ( bSuccess )
						Debug.Log( "Bundle " + sBundleName + ".assetbundle successfuly created." );
					else
						Debug.LogError( "Can't create Bundle " + sBundleName + ".assetbundle" );
				}
			}
		}
		xr.Close();
	}
	
	/////////////////////////////// 
	
	void WriteLangs(int xMask)
	{
		StreamWriter sw = new StreamWriter(langPath);
		
		if (sw != null)
		{
			string sText = "ID;NAME\n";
			
			for (int i=0; i< bLanguages.Length; i++)
			{
				if ((xMask & (1<<i)) != 0)
				{
					if(i < latinLangs.Length)
						sText += latinSuffixes[i] + ";" + latinLangs[i] + "\n";
					else
						sText += suffixes[i - latinLangs.Length + 1] + ";" + languages[i - latinLangs.Length + 1] + "\n";
				}
			}
			
			sw.Write( sText );
			sw.Close();
			
			RC4 rc4 = new RC4();
			byte[] sEncryptedText = rc4.Encrypt( sText );
			
			using( BinaryWriter binaryWriter = new BinaryWriter( File.Open( langEncPath, FileMode.Create ) ) )
	        {
				binaryWriter.Write( sEncryptedText );
			}
		}
		else
		{
			Debug.LogError("Unable to write to " + langPath);
		}

		AssetDatabase.Refresh();
	}
		
	System.Diagnostics.Process StartProcess(string executable, string arguments, string subPath)
	{
		System.Diagnostics.Process p = new System.Diagnostics.Process();
		p.StartInfo.FileName = executable;
		p.StartInfo.Arguments = arguments;       
		p.StartInfo.RedirectStandardError=true;
		p.StartInfo.RedirectStandardOutput=true;
		p.StartInfo.CreateNoWindow=true;
		string sWorkingDir = Application.dataPath + "/../" + subPath;
		p.StartInfo.WorkingDirectory = sWorkingDir; //.Replace( "/", "\\");
		//Debug.Log("wdir:" + p.StartInfo.WorkingDirectory);
		//Debug.Log("WorkingDirectory = " + p.StartInfo.WorkingDirectory + "\nargs = " + arguments);
		p.StartInfo.UseShellExecute=false;
		p.Start();
		return p;
	}
	
	void RunProcess(string executable, string arguments, string subPath)
	{
		System.Diagnostics.Process p = StartProcess(executable, arguments, subPath);
		//Debug.Log(p.StandardOutput.ReadToEnd());
		while (!p.WaitForExit(1000));
	}
	
	void BuildLanguages()
	{
		Debug.Log( "Builds Languages start" );
		int xMask = 0;
		for(int i = 0; i < bLanguages.Length; i++)
		{
			if(bLanguages[i])
				xMask |= 1 << i;
		}
		WriteLangs(xMask);
		
		// On change le panneau de victoire en fonction des langues
		//changeEndLevel();
		
		Debug.Log( "Builds Languages end" );
	}
	
	void BuildFont( int xMask )
	{
		string sLangExt;
		
		for(int i = 0; i < languages.Length; i++)
		{
			if( ( xMask & ( 1 << i ) ) != 0 )
			{
				if( suffixes[i] == "LN" )
					sLangExt = "";
				else
					sLangExt = "_" + suffixes[i];
				
				BuildAssetBundle( Application.dataPath + "/../../Data/" + "AssetBundles/Fonts" + sLangExt + ".xml" );
			}
		}
	}
	
	void lwBuildSettingsFile()
	{
		if( !File.Exists( settingsPath ) )
		{
			Debug.LogWarning( "Unable to read " + settingsPath );
			return;
		}
		
		using( BinaryReader binaryReader = new BinaryReader( File.Open( settingsPath, FileMode.Open, FileAccess.Read ) ) )
		{
			RC4 rc4 = new RC4();
			byte[] fileContent = binaryReader.ReadBytes( (Int32)new FileInfo( settingsPath ).Length );
			byte[] sEncryptedText = rc4.Encrypt( fileContent );
			
			using( BinaryWriter binaryWriter = new BinaryWriter( File.Open( settingsEncPath, FileMode.Create ) ) )
	        {
				binaryWriter.Write( sEncryptedText );
			}
		}

		AssetDatabase.Refresh();
	}
	
	void Update()
	{
		int i;
		
		if(!m_bInitDone)
			InitAll();
		
		//AB CREATOR
		State lastState = m_nState;
		m_nState = State.None;
		switch( lastState )
		{
		case State.BuildAB:
			BuildAssetBundles();
			break;
		}
		
		if( bBuildFonts )
		{
			Debug.Log( "Builds Fonts start" );
			bBuildFonts = false;
			
			for( i = 0; i < languages.Length; i++ )
				if( versions[i] )
					BuildFont( 1 << i );
			
			Debug.Log( "Builds Fonts end" );
		}
		
		if( bBuildLanguages )
		{
			bBuildLanguages = false;
			BuildLanguages();
		}
		
		if( bBuildGame )
		{
			bBuildGame = false;
			
			if(targetList[nSelectedIndexTarget] != EditorUserBuildSettings.activeBuildTarget)
				SwitchPlatform();
			
			PreBuildAssetHolder();
			
			string sFullPath = Application.dataPath + "/../../Build/" + targetListName[nSelectedIndexTarget] + "/" + lwBuildSettings.GetGameVersionName();
			
			switch(EditorUserBuildSettings.activeBuildTarget)
			{
				case BuildTarget.StandaloneWindows :
					sFullPath += ".exe";
					break;
				case BuildTarget.Android :
					sFullPath += ".apk";
					break;
				case BuildTarget.StandaloneOSXIntel :
					sFullPath += ".app";
					break;
			}
			
			string[] scenes = new string[EditorBuildSettings.scenes.Length];
			for(i = 0; i < EditorBuildSettings.scenes.Length; i++)
			{
				scenes[i] = EditorBuildSettings.scenes[i].path;
			}
			
			BuildPipeline.BuildPlayer( scenes, sFullPath, EditorUserBuildSettings.activeBuildTarget, IsReleaseBuild() ? BuildOptions.None : BuildOptions.Development); 
			
			PostBuildAssetHolder();
		}
		
	}
	
	void SwitchPlatform()
	{
		if(targetList[nSelectedIndexTarget] == BuildTarget.Android || EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
		{
			if(targetList[nSelectedIndexTarget] == BuildTarget.Android)
				File.Copy(Application.dataPath + "/../../Data/Shaders/Android/Shader2DRuntime.shader", Application.dataPath + "/Shaders/Shader2DRuntime.shader", true);
			else 
				File.Copy(Application.dataPath + "/../../Data/Shaders/Normal/Shader2DRuntime.shader", Application.dataPath + "/Shaders/Shader2DRuntime.shader", true);
			AssetDatabase.Refresh();
		}
		
		EditorUserBuildSettings.SwitchActiveBuildTarget(targetList[nSelectedIndexTarget]);
	}
	
	void PreBuildAssetHolder()
	{	
		
		string sXmlConfiguration = Application.dataPath + "/AssetHolders/" + lwBuildSettings.GetGameVersionName() + "/AssetHolder.xml";
		if(File.Exists(sXmlConfiguration))
		{
			if(!Directory.Exists(Application.dataPath + "/Generated/Resources/"))
			{
				Directory.CreateDirectory(Application.dataPath + "/Generated/Resources/");
				AssetDatabase.SaveAssets();
				AssetDatabase.Refresh();
			}
			else
			{
				Directory.Delete(Application.dataPath + "/Generated/", true);
				Directory.CreateDirectory( Application.dataPath + "/Generated/Resources/" );
				AssetDatabase.SaveAssets();
				AssetDatabase.Refresh();
			}

			if(File.Exists(Application.dataPath + "/Generated/Resources.meta"))
				File.Delete(Application.dataPath + "/Generated/Resources.meta");
			File.Move(Application.dataPath + "/AssetHolders/Resources.meta", Application.dataPath + "/Generated/Resources.meta");
			
			string[] sTarget = {"WINDOWS", "MAC", "ANDROID", "IOS", "WEB"};
			BuildTarget[] pBuildTarget = {BuildTarget.StandaloneWindows, BuildTarget.StandaloneOSXIntel, BuildTarget.Android, BuildTarget.iPhone, BuildTarget.WebPlayer};
			
			XmlDocument xmlDoc = new XmlDocument();
	
		    xmlDoc.Load(sXmlConfiguration);
		
		    XmlNodeList nodeList = xmlDoc.GetElementsByTagName("ASSETARRAY");
			
			string sAssetName = string.Empty;
			string sTargetValue = string.Empty;
			
			
			for(int i = 0; i < nodeList.Count; i++)
			{
				sAssetName = nodeList[i].Attributes["name"].Value;
				
				//Si la target n'est pas à null on donne la valeur à notre TargetValue sinon on met empty
				if(nodeList[i].Attributes["target"] != null)
					sTargetValue = nodeList[i].Attributes["target"].Value;
				else
					sTargetValue = string.Empty;
				
				if(!string.IsNullOrEmpty(sAssetName))
				{
					bool bCopy = false;
					
					if(!string.IsNullOrEmpty(sTargetValue))
					{
						for(int j = 0; j < sTarget.Length; j++)
						{
							if(sTargetValue.Contains(sTarget[j]) && EditorUserBuildSettings.activeBuildTarget == pBuildTarget[j])
							{
								bCopy = true;
							}
						}
					}
					else
						bCopy = true;
					
					if(bCopy)
					{
						XmlNodeList pathList = nodeList[i].ChildNodes;
						for(int j = 0; j < pathList.Count; j++)
						{
							string pathAsset = pathList[j].Attributes["path"].Value;
							if( !string.IsNullOrEmpty(pathAsset) && File.Exists( Application.dataPath + "/AssetHolders/Resources/" + pathAsset ) )
							{
								Directory.CreateDirectory( Application.dataPath + "/Generated/Resources/" + Path.GetDirectoryName(pathAsset));
								File.Move( Application.dataPath + "/AssetHolders/Resources/" + pathAsset, Application.dataPath + "/Generated/Resources/" + pathAsset);
								File.SetAttributes( Application.dataPath + "/Generated/Resources/" + pathAsset, FileAttributes.Normal );
								File.Move( Application.dataPath + "/AssetHolders/Resources/" + pathAsset + ".meta", Application.dataPath + "/Generated/Resources/" + pathAsset + ".meta" );
								File.SetAttributes( Application.dataPath + "/Generated/Resources/" + pathAsset + ".meta", FileAttributes.Normal );
							}
						}
					}
				}
				else
					Debug.LogWarning(sAssetName + " has an invalid parameter.");
			}
			
			File.Copy(sXmlConfiguration, Application.dataPath + "/Generated/Resources/" + Path.GetFileName(sXmlConfiguration));
			File.Copy(sXmlConfiguration + ".meta", Application.dataPath + "/Generated/Resources/" + Path.GetFileName(sXmlConfiguration) + ".meta");
			
			Directory.Move(Application.dataPath + "/AssetHolders/Resources/", Application.dataPath + "/AssetHolders/ResourcesNotBuilt/");
			AssetDatabase.SaveAssets();
			AssetDatabase.Refresh();
		}		
	}	
	
	void PostBuildAssetHolder()
	{
		string sXmlConfiguration = Application.dataPath + "/AssetHolders/" + lwBuildSettings.GetGameVersionName() + "/AssetHolder.xml";
				
		if(!File.Exists(sXmlConfiguration))
			return;
		
		if(Directory.Exists(Application.dataPath + "/AssetHolders/ResourcesNotBuilt/"))
		{
			Directory.Move(Application.dataPath + "/AssetHolders/ResourcesNotBuilt/", Application.dataPath + "/AssetHolders/Resources/");
			File.Delete(Application.dataPath + "/AssetHolders/ResourcesNotBuilt.meta");
		}	

		string generatedResourcesPath = Application.dataPath + "/Generated/Resources/";
		if( Directory.Exists( Application.dataPath + "/Generated/Resources/" ) )
		{
			int subCount = generatedResourcesPath.Length;
			File.Move(Application.dataPath + "/Generated/Resources.meta", Application.dataPath + "/AssetHolders/Resources.meta");
//			foreach(string pathFile in Directory.GetFiles( Application.dataPath + "/Generated/Resources/", "*", SearchOption.AllDirectories ) )
			foreach(string pathFile in this.GetFiles( Application.dataPath + "/Generated/Resources/" ) )
			{
				if(!File.Exists(Application.dataPath + "/AssetHolders/Resources/" + pathFile.Substring(subCount)))
					File.Move(pathFile, Application.dataPath + "/AssetHolders/Resources/" + pathFile.Substring(subCount));
			}
			
			Directory.Delete( Application.dataPath + "/Generated/", true );
			File.Delete(Application.dataPath + "/Generated.meta");
		}
		
		AssetDatabase.SaveAssets();
		AssetDatabase.Refresh();
	}
	
	static IEnumerable<string> GetFiles( string path )
	{
	    Queue<string> queue = new Queue<string>();
	    queue.Enqueue(path);
	    while (queue.Count > 0)
		{
	        path = queue.Dequeue();
	        try {
	            foreach ( string subDir in Directory.GetDirectories( path ) )
	                queue.Enqueue(subDir);
	        }
	        catch(Exception ex) {
	            Console.Error.WriteLine(ex);
	        }
	        string[] files = null;
	        try {
	            files = Directory.GetFiles(path);
	        }
	        catch (Exception ex) {
	            Console.Error.WriteLine(ex);
	        }
	        if (files != null)
	            for(int i = 0 ; i < files.Length ; i++)
	                yield return files[i];
    	}
	}
}

